home *** CD-ROM | disk | FTP | other *** search
- .NT
- A NOTE ABOUT THE LESSONS in C
- .b4-24R5C4
- These were written while the author was ~Ilearning~N the language and since
- .R6C4
- they are ~Ifree~N ( to copy and/or distribute ) there is a money-back
- .R7C4
- guarantee on the accuracy of each and every statement in the lessons (!)
- .R9C4
- The ~Idisplay~N program was written ( in C ) in order to provide a vehicle
- .R10C4
- for displaying the lessons.
- .R12C5
- .B
- P.J.Ponzo
- .B
- Dept. of Applied Math
- .B
- Univ. of Waterloo
- .B
- Ontario N2L 3G1
- .K16,32
- PonzoTUTOR
- .WNT
- FIELDS
- .R5C1
- Suppose we wish to manipulate the results of a questionnaire containing
- 20 questions with answers either YES or NO. If we store the answers in an
- ~n~Iint~Neger variable ~b~Ix~N, with x=1 corresponding to a YES answer and
- x=0 to a NO, then (since integers occupy 2 bytes of memory, usually) this
- would require 40 bytes per questionnaire and, if 1000 people answered the
- questionnaire the results would occupy 40,000 bytes ... too much!!
-
- ~ISO~N, we store the answers in a 1-byte ~b~Ichar~Nacter variable ~b~Ix~N with
- either x='Y' or x='N. That would take 20,000 bytes of memory ... too much!
-
- ~ISO~N (since 1=YES and 0=NO only needs ~I1 bit~N of memory) we store the
- results in 20,000 ~Ibits~N ... let's see ... at 8 bits per byte that would
- take ... 20000/8=~I2500~N bytes ... just right.
-
- Is there a DATA TYPE called ~b~Ibit~N (so we could declare ~b~Ibit x;~N) ?
- Alas, there is NOT ... but we ~Ican~N create a ~Istructure~N with members which
- occupy ~Ibits~N of memory!
- .WN
- ~b~I struct byte { /* define a structure called byte */ ~N
- ~b~I unsigned member1 : 1; /* member occupies 1 bit */ ~N
- ~b~I unsigned member2 : 4; /* member occupies 4 bits */ ~N
- ~b~I unsigned member3 : 3; /* member occupies 3 bits */ ~N
- ~b~I } x; /* declare x to be such a structure */ ~N
-
- Now ~b~Ix~N is a structure of type ~b~Ibyte~N which has 3 members (in this example).
- Each member is an ~b~Iunsigned~N integer.
- These members are made to occupy a number of ~Ibits~N.
- The colon ~b~I : ~N followed by an integer (like 1,4 and 3) arranges this for
- us.
-
- Now we can (as usual) refer to ~b~Ix.member1~N, ~b~Ix.member2~N and ~b~Ix.member3~N
- and (for example) say: ~b~Ix.member1=0;~N or ~b~Ix.member2=13;~N, etc.
-
- Since ~b~Ix.member1~N is 1 bit wide, it will hold numbers 0 and 1 only.
- Since ~b~Ix.member2~N is 4 bits wide, it will hold numbers 0,1,2,..., 15.
- Since ~b~Ix.member3~N is 3 bits wide, it will hold numbers 0,1,2,..,7.
-
- .w
- ... and the whole structure, with all 3 members, only fills one byte of
- memory (since 1+4+3 bits =1 byte).
-
- ~IThe members, occupying a number of adjacent bits in memory, are called~N
- ~V FIELDS ~N
- .WN
- If we define another struct called bytes, and declare *x ...
- ~b~I struct bytes { /* define a structure called bytes */ ~N
- ~b~I unsigned member1 : 1; /* member occupies 1 bit */ ~N
- ~b~I unsigned member2 : 4; /* member occupies 4 bits */ ~N
- ~b~I unsigned member3 : 4; /* member occupies 3 bits */ ~N
- ~b~I } *x; /* declare x to be a pointer */ ~N
- so that ~b~Ix~N is now a ~r~Ipointer~N to a structure, then we would access
- a member with: ~b~Ix->member1~N (remember?)
-
- If you're really squeezed for memory space, then cram as much into a
- 2-byte integer as possible by using ~Ibits~N.
-
- Note that, in the above structure, we now have 1+4+4 bits which is more
- than a byte will hold, so the compiler will put ~b~Imember3~N into a
- second byte (and "waste" the remaining 3 bits of the first byte and
- probably the remaining 4 bits of the second byte too!)
-
- .K17,32
- 8bits/byte
- .WNT
- UNIONS
- .R5C1
- If you're still in need of memory space you can arrange to have several
- variables occupy the ~Isame~N memory space ... but not at the same time
- (of course).
-
- This union of variables is called a ... ~V UNION ~N (what else?)
- ~b~I union sam { /* define a union called sam */ ~N
- ~b~I int x; /* the first member is an int */ ~N
- ~b~I float y; /* the second member is a float */ ~N
- ~b~I char z; /* the third member is a char */ ~N
- ~b~I } jeckyl, *hyde; /* declare some unions */ ~N
-
- Since these 3 variables ~b~Ix~N, ~b~Iy~N and ~b~Iz~N occupy different amounts
- of memory the variable ~b~Ijeckyl~N will occupy sufficient memory to hold
- the largest of ~b~Ix~N, ~b~Iy~N and ~b~Iz~N (in this case, it's ~b~Iy~N).
-
- You may point to a union ( ~b~Ihyde~N is a ~r~Ipointer~N)
- and/or access one of its members ( ~b~Ijeckyl.x=123~N or ~b~Ihyde->z='A'~N ).
- .WN
- ~b~I union sam { /* define a union called sam */ ~N
- ~b~I int x; /* the first member is an int */ ~N
- ~b~I float y; /* the second member is a float */ ~N
- ~b~I char z; /* the third member is a char */ ~N
- ~b~I } jeckyl, *hyde; /* declare some unions */ ~N
-
- If you say: ~b~Ijeckyl.x=123~N ( an integer ) then the space set aside for
- ~b~Ijeckyl~N will be occupied (in part) by the integer ~b~I123~N.
-
- If you then say: ~b~Iprintf("%f",jeckyl.y);~N the printf function will go
- to the memory location where jeckyl lives, interpret the 2-byte ~b~Iint~N
- ~I123~N as a 7-byte float ('cause we said ~b~I%f~N) and print garbage!
- .K19,60
- MORAL?
- .W
- ~V ~N
- ~V jeckyl and *hyde will contain an int, float or char depending upon ~N
- ~V whether the last thing you put there was an int, float or char! ~N
- ~V ~N
- .WN
-
- So, keep track with some variable called WhoThere.
-
- ~b~I#define CHAR 1 ~N
- ~b~I#define INTEGER 2 ~N
- ~b~I#define FLOAT 3 ~N
- ~b~I .................. ~N
- ~b~Iint WhoThere; ~N
- ~b~I .................. ~N
-
- Each time you say:
-
- ~b~Ihyde->y=12.34;~N then also say: ~b~IWhoThere=FLOAT;~N
-
- so you can check if ~b~IWhoThere==CHAR~N or ~b~IWhoThere==INTEGER~N etc.
-
- to see who's currently a member of this union!
- .K3,60
- easy eh?
- .WN
-
-
- .T
- That's all folks!
- .K16,32
- au revoir!
-
-
- .q
-
-